package com.pie4cloud.pie.job.executor.utils.netty;

import com.pie4cloud.pie.dmz.handler.MsgDecoder;
import com.pie4cloud.pie.dmz.handler.MsgEncoder;
import com.pie4cloud.pie.dmz.handler.NettyUpDownHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
import java.net.SocketAddress;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class NettyClient {
	@Autowired
	private NettyUpDownHandler nettyUpDownHandler;

	private EventLoopGroup group = new NioEventLoopGroup(1);
	private Bootstrap bootstrap = new Bootstrap();

	public NettyClient(){
		bootstrap.group(group).
				channel(NioSocketChannel.class).
				option(ChannelOption.TCP_NODELAY, true).
				option(ChannelOption.SO_KEEPALIVE,true).
				handler(new ChannelInitializer<SocketChannel>() {
					//创建NIOSocketChannel成功后，在进行初始化时，将它的ChannelHandler设置到ChannelPipeline中，用于处理网络IO事件
					protected void initChannel(SocketChannel channel) throws Exception {
						ChannelPipeline pipeline = channel.pipeline();
						//pipeline.addLast(new IdleStateHandler(0, 0, 30));
						pipeline.addLast(new MsgEncoder());
						pipeline.addLast(new MsgDecoder());
						pipeline.addLast(new ReadTimeoutHandler(10, TimeUnit.MINUTES));
						pipeline.addLast("handler", nettyUpDownHandler);
					}
				});
	}

	@PreDestroy
	public void destroy(){
		log.info("RPC客户端退出,释放资源!");
		group.shutdownGracefully();
	}


	public Channel doConnect(SocketAddress address) throws InterruptedException {
		ChannelFuture future = bootstrap.connect(address);
		Channel channel = future.sync().channel();
		return channel;
	}
}
